package jp.reflexworks.atom;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jp.reflexworks.atom.entry.Author;
import jp.reflexworks.atom.entry.Category;
import jp.reflexworks.atom.entry.Content;
import jp.reflexworks.atom.entry.Contributor;
import jp.reflexworks.atom.entry.Entry;
import jp.reflexworks.atom.entry.Link;
import jp.reflexworks.atom.feed.Feed;
import jp.reflexworks.atom.source.Generator;
import jp.reflexworks.atom.source.Source;
import jp.reflexworks.atom.util.DateUtil;
import jp.reflexworks.atom.util.JdoUtils;
import jp.sourceforge.reflex.IResourceMapper;
import jp.sourceforge.reflex.core.ResourceMapper;

import com.google.appengine.api.datastore.Text;

public class ReflexAtomServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		resp.setContentType("text/plain");
		resp.setCharacterEncoding("UTF-8");

		// Entry
        Entry entry = new Entry();
        entry.author = new ArrayList<Author>();
        Author author = new Author();
        author.email = "foo@bar.jp";
        author.name ="foo";
        author.uri = "abc";
        entry.author.add(author);

        Category category = new Category();

        category._$label = "reflex itext";
        entry.category = new ArrayList<Category>();
        entry.category.add(category);

        entry.contributor = new ArrayList<Contributor>();

        Contributor contributor = new Contributor();
        contributor.name ="田中";
        entry.contributor.add(contributor);
        entry.title = "Atom sft test";    // Entry's title.
        
        entry.link = new ArrayList<Link>();
        Link link4 = new Link();

        link4._$href="http://example.org/2009/05/23/atom";
        link4._$rel="alternate";
        link4._$type="text/html";
        entry.link.add(link4);

        Link link5 = new Link();
        link5._$href="http://example.org/audio/ph34r_my_podcast.mp3";
        link5._$rel="enclosure";
        link5._$type="audio/mpeg";
        link5._$length="1337";
        entry.link.add(link5);
        
        entry.content = new Content();
        entry.content._$$text = new Text("<div xmlns=\"http://www.w3.org/1999/xhtml\">" +
        		"<p><i>[Update: The Atom draft is finished.]</i></p></div>");
        entry.content._$type = "xhtml";
        entry.content._$xml$base = "http://diveintomark.org/";
        entry.content._$xml$lang = "en";
        entry.updated = DateUtil.getDateTime(new Date());

        // Source
        entry.source = new Source();
        
        Generator generator = new Generator();
        entry.source.generator = generator;
        
        generator._$xml$base = "http://diveintomark.org/";
        generator._$xml$lang = "en";
        generator._$uri = "xxxxx";
        generator._$version = "1.0";
        
        entry.source._$xml$base = "aaaa";
        entry.source.title = "Source Title";
        
		// モデルビーンのパッケージ名を指定してリソースマッパーをnewする
		Map<String,String> param = new HashMap<String,String>();
		
        param.put("jp.reflexworks.atom.feed","http://www.w3.org/2005/Atom");	// パッケージ名と名前空間のペアを指定する	
        param.put("jp.reflexworks.atom.entry","");								// 名前空間""はデフォルト空間
		param.put("jp.reflexworks.atom.source","");				
		
		IResourceMapper mapper = new ResourceMapper(param);		// mapをパラメータにしてMapperをnewする
 
		// そしてXMLにシリアライズ
		String toXML = mapper.toXML(entry);
		resp.getWriter().print("\n【EntryをXMLにシリアライズ】");
		resp.getWriter().println("\n");
		resp.getWriter().println(toXML);

		// デシリアライズテスト
		resp.getWriter().print("\n【Entryのデシリアライズテスト】");
		resp.getWriter().println("\n");
		Entry entry2 = (Entry) mapper.fromXML(toXML);

		//
		Feed feed = new Feed();
		feed._$xmlns = "http://www.w3.org/2005/Atom";
		feed.title = "Example Feed";
		feed.link = new ArrayList<jp.reflexworks.atom.feed.Link>();
		jp.reflexworks.atom.feed.Link link3  = new jp.reflexworks.atom.feed.Link();
		link3._$href = "http://example.org/";
		
		feed.link.add(link3);
		feed.entry = new ArrayList<Entry>();
		feed.entry.add(entry);

		feed.updated = DateUtil.getDateTime(new Date());
		feed.author = new ArrayList<jp.reflexworks.atom.feed.Author>();
		jp.reflexworks.atom.feed.Author author2 = new jp.reflexworks.atom.feed.Author();
		author2.name = "Takezaki";
		author2.uri = "http://blog.virtual-tech.net";
		feed.author.add(author2);
		
		// そしてXMLにシリアライズ
		toXML = mapper.toXML(feed);
		resp.getWriter().print("\n【Feedを生成して上のEntryを追加】");
		resp.getWriter().println("\n");
		resp.getWriter().println(toXML);

		// デシリアライズテスト

		Feed feed2 = (Feed) mapper.fromXML(toXML);

		// そしてXMLにシリアライズ
		toXML = mapper.toXML(feed2);
		resp.getWriter().print("\n【Feedのデシリアライズテスト】");
		resp.getWriter().println("\n");
		resp.getWriter().println(toXML);
/*
		// Datastoreに格納
		resp.getWriter().print("\n【Datastoreに格納】");
		resp.getWriter().println("\n");
		JdoUtils.insert(feed2);
*/
		// entryのAuthorをfeedのAuthorにDeepCopy
		resp.getWriter().print("\n【entryのAuthorをfeedのAutorにDeepcopy】");
		resp.getWriter().println("\n");
		IResourceMapper mapper2 = new ResourceMapper("jp.reflexworks.atom.feed");
		resp.getWriter().println("\n");
		jp.reflexworks.atom.feed.Author author3 = (jp.reflexworks.atom.feed.Author) mapper2.fromXML(mapper.toXML(author));

		// それをXMLにシリアライズ
		toXML = mapper2.toXML(author3);
		resp.getWriter().println(toXML);

		
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		resp.setContentType("text/plain");
		resp.setCharacterEncoding("UTF-8");

		// モデルビーンのパッケージ名を指定してリソースマッパーをnewする
		Map<String,String> param = new HashMap<String,String>();
		
        param.put("jp.reflexworks.atom.feed","http://www.w3.org/2005/Atom");	// パッケージ名と名前空間のペアを指定する	
        param.put("jp.reflexworks.atom.entry","");								// 名前空間""はデフォルト空間
		param.put("jp.reflexworks.atom.source","");				
		
		IResourceMapper mapper = new ResourceMapper(param);		// mapをパラメータにしてMapperをnewする

		// デシリアライズテスト
		resp.getWriter().print("\n【オリジナルのFeed】");
		resp.getWriter().println("\n"+req.getParameter("xml"));

		Feed feed = (Feed) mapper.fromXML(req.getParameter("xml"));

		resp.getWriter().println("\n【content】:"+feed.entry.get(0).content._$$text.getValue());
		
		
		// XMLにシリアライズ
		String toXML = mapper.toXML(feed);
		resp.getWriter().println("\n【デシリアイアライズされたFeed】:");
		resp.getWriter().println("\n:");
		resp.getWriter().println(toXML);
		
		// Datastoreに格納
		resp.getWriter().print("\n【Datastoreに格納】");
		resp.getWriter().println("\n");
		JdoUtils.insert(feed);

		// INSERTしたものを読み取る
		List<Feed> feeds = JdoUtils.getFeeds();

		resp.getWriter().println("\n【DataStoreに格納されているものを全部取り出して表示】");
		
		for (Feed aFeed : feeds) {

			// XMLにシリアライズ
			toXML = mapper.toXML(aFeed);
			resp.getWriter().println("\n【Feed】:");
			resp.getWriter().println("\n:");
			resp.getWriter().println(toXML);
			
		}
		
	}

	
}
